﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using wUniAppPCL.IO;
using wUniAppPCL.Loacalization;

namespace wUniAppPCL.MVVM
{
  public class BaseModel : wObservableObject
  {
    public BaseModel(IwStorage storage, string xmlFileName, IwBaseMessage msgDialog)
    {
      Patients = new PatientsViewModel();
      Patients.SelectedItemChanged += Patients_SelectedItemChanged;
      FilteredPatients = new FilteredPatientsViewModel(Patients);
      Siblings = new DetailViewModel(Patients);

      Storage = storage;
      XmlFileName = xmlFileName;
      MsgDialog = msgDialog;



      if (storage == null)
      {
        IList<Person> pi = Patients.Items;
        PatientsViewModel.GenerateTestData(ref pi);
        FilteredPatients.LoadFromSource();
        Siblings.Averages.Items = Patients.Items;
      }
      else
      {
        wFileStream wfs = new wFileStream(Storage, XmlFileName);
        px = new PatientsXml(wfs);

        //IList<Person> pix = Patients.Items;
        //PatientsViewModel.GenerateTestData(ref pix, 10000);
        //SaveToXml();

        LoadFromXml(() =>
        {
          FilteredPatients.LoadFromSource();
          Siblings.Averages.Items = Patients.Items;
        });
      }

    }


    void Patients_SelectedItemChanged(object sender, SelectedItemChangedEventArgs<Person> e)
    {
      {
      //  int t = Environment.TickCount;

       if (e.NewValue != null)
       {
         Siblings.SetFilter(e.NewValue.LastName);
       }
       Siblings.SelectedItem = e.NewValue;
    //    t = Environment.TickCount - t;
    //    wLogger.ToLog(t.ToString());
      }
    }

    IwStorage Storage;
    IwBaseMessage MsgDialog;
    string XmlFileName;
    PatientsXml px;
 
    FilterHelper<Person> siblingFilter;
    public FilterHelper<Person> SiblingFilter
    {
      get
      {
        if (siblingFilter == null) siblingFilter = new FilterHelper<Person>();
        return siblingFilter;
      }
    }

    private string filterText = "";
    public string FilterText
    {
      get { return filterText; }
      set { SetProperty(ref filterText, value, "FilterText"); }
    }

    public PatientsViewModel Patients { get; set; }
    public FilteredPatientsViewModel FilteredPatients { get; set; }
    public DetailViewModel Siblings { get; set; }

    /// <summary>
    /// strings for filter method B , default separator ';' 
    /// </summary>
    /// <param name="postFixes"></param>
    protected void SetPostFixes(string postFixes, char separator = ';')
    {
      string[] pfa = postFixes.Split(separator);
      FilterHelper<Person>.PostFixArray = pfa;
    }

    private ICommand insertCommand;
    public ICommand InsertCommand
    {
      get
      {
        return insertCommand ??
               (insertCommand = new RelayCommand(() =>
               {
                 Patients.Insert(new Person());
                 //SaveToXml();
               }));
      }
    }

    private ICommand deleteCommand;
    public ICommand DeleteCommand
    {
      get
      {
        return deleteCommand ??
               (deleteCommand = new RelayCommand(async () =>
               {
                 var res = await MsgDialog.Show(Resources.ReallyQuestion, wMessageDlgTypeEnum.YesNo);
                 if (res == wMessageDlgResultEnum.Yes)
                 {
                   Patients.Delete(Patients.SelectedItem);
                   //SaveToXml();
                 }
               }));
      }
    }

    private ICommand saveCommand;
    public ICommand SaveCommand
    {
      get
      {
        return saveCommand ??
               (saveCommand = new RelayCommand(async () =>
               {
                 var res = await MsgDialog.Show(Resources.ReallyQuestion, wMessageDlgTypeEnum.YesNo);
                 if (res == wMessageDlgResultEnum.Yes)
                 {
                   SaveToXml();
                 }
               }));
      }
    }

    private ICommand searchCommand;
    public ICommand SearchCommand
    {
      get
      {
        return searchCommand ??
               (searchCommand = new RelayCommand(() =>
               {
                 Search();
               }));
      }
    }

    private ICommand avgHeightCommand;
    public ICommand AvgHeightCommand
    {
      get
      {
        return avgHeightCommand ??
               (avgHeightCommand = new RelayCommand(() =>
               {
                 double avgHeight = Patients.GetAvgHeight();
                 MsgDialog.Show(String.Format("{0} (Task 1 - B) : {1}", Resources.AvgHeight, avgHeight), wMessageDlgTypeEnum.OK);
               }));
      }
    }



    public void Search()
    {
      FilteredPatients.SetFilter(FilterText);
    }

    public async void LoadFromXml(Action asyncResultCallback = null)
    {
      try
      {
        Patients.Items.Clear();
        PatientsViewModel res = await px.Load();
        Patients.Items.AddRange(res.Items);
        if (asyncResultCallback != null)
        {
          asyncResultCallback();
        }
      }
      catch (Exception ex)
      {
        wLogger.ToLog(ex);
      }
    }

    public async void SaveToXml()
    {
      try
      {
        if (px != null)
        {
          await px.Save(Patients);
        }
      }
      catch (Exception ex)
      {
        wLogger.ToLog(ex);
      }
    }

  }
}
